# -*- coding: UTF-8 -*-

import math

import pygtk
pygtk.require('2.0')

import gobject
import gtk
from gtk import gdk

#
# Transparency is implemented using Cairo and Pango libraries.
#
# As I was told in #gtk+ at irc.gnome.org, I could use an RGBA window,
# but it would lead to many many problems I'd have to avoid. So I
# was advised to ignore this hint.
#

class TransparentLabel(gtk.Widget):
    def __init__(self, text=''):
        gtk.Widget.__init__(self)

        self.__text = text
        self.__color = [0, 0, 0, 1]
        self.__pos = gtk.POS_TOP

    def set_text(self, text):
        assert text is not None
        if self.__text != text:
            self.__text = text
            self.queue_resize()

        #
        # To set aplha separate of RGB colors we need to pass to
        # cairo_context.set_source(r, g, b, a) R, G and B
        # values that are already there.
        #
        # But cairo context does not provide any methods to
        # do this. And I do not know how to get foreground color
        # settings from our widget style.
        #
        # So I have to provide our own method to set color - set_rgb()
        # instead of modify_fg() provided by gtk.Widget.
        #

    def set_rgba(self, r, g, b, a):
        assert r >= 0 and r <= 1 \
           and g >= 0 and g <= 1 \
           and b >= 0 and b <= 1 \
           and a >= 0 and a <= 1
        if self.__color != [r, g, b, a]:
            self.__color = [r, g, b, a]
            self.queue_draw()

    def set_rgb(self, r, g, b):
        assert r >= 0 and r <= 1 \
           and g >= 0 and g <= 1 \
           and b >= 0 and b <= 1
        if self.__color[:3] != [r, g, b]:
            self.__color[:3] = [r, g, b]
            self.queue_draw()

    def set_alpha(self, a):
        assert a >= 0 and a <= 1
        if self.__color[3] != a:
            self.__color[3] = a
            self.queue_draw()

    def set_pos(self, gtk_pos):
        if gtk_pos == gtk.POS_BOTTOM:
            gtk_pos = gtk.POS_TOP
        if self.__pos != gtk_pos:
            if self.__pos == gtk.POS_TOP or gtk_pos == gtk.POS_TOP:
                self.queue_resize()
            self.__pos = gtk_pos

    # --------------------

    def do_realize(self):
        self.set_flags(gtk.REALIZED | gtk.NO_WINDOW)
        self.window = self.get_parent_window()
        self.style.attach(self.window)

    def do_size_request(self, req):
        if self.__pos == gtk.POS_TOP:
            req.width, req.height = self.__get_layout().get_pixel_size()
        else:
            req.height, req.width = self.__get_layout().get_pixel_size()

    def do_expose_event(self, event):
        context = event.window.cairo_create()
        context.rectangle(
          event.area.x,
          event.area.y,
          self.allocation.width,
          self.allocation.height)
        context.clip()

        context.move_to(self.allocation.x, self.allocation.y)
        if self.__pos == gtk.POS_LEFT:
            context.rel_move_to(self.allocation.width, 0)
            context.rotate(math.pi / 2)
        elif self.__pos == gtk.POS_RIGHT:
            context.rel_move_to(0, self.allocation.height)
            context.rotate(-math.pi / 2)
        context.set_source_rgba(*self.__color)

        layout = self.__get_layout()
        context.update_layout(layout)
        context.show_layout(layout)
        return False

    # --------------------

    def __get_layout(self):
        return self.create_pango_layout(self.__text)

gobject.type_register(TransparentLabel)
